home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 May
/
EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso
/
earcd
/
util
/
sys
/
msys_1_2.lha
/
Src
/
loadwb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-23
|
13KB
|
418 lines
/*
** loadwb.c - start Workbench
** $VER: loadwb.c 42.2 (23.7.96)
** Copyright © 1996 Michal Letowski
**
** 42.1 (10.2.96) - initial version
** 42.2 (23.7.96)
** + added RAMICON/S option
*/
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/libraries.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <workbench/workbench.h>
#include <support/types.h>
#include <support/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/wb.h>
#include "loadwb.rev.h"
/*
** Constants
*/
#define DOS_NAME "dos.library"
#define DOS_VERN 37L
#define WB_NAME "workbench.library"
#define WB_VERN 39L
#define ICON_NAME "icon.library"
#define ICON_VERN 37L
#define TEMPLATE "DEBUG=-DEBUG/S,DELAY/S,CLEANUP/S,NEWPATH/S,HIDE/S,RAMICON/S"
#define SRC_ICON "ENV:Sys/def_ramdisk"
#define DST_ICON "RAM:Disk"
#define WBB_DEBUG 0 /* Turn on debug menu */
#define WBF_DEBUG (1<<WBB_DEBUG)
#define WBB_DELAY 1 /* Wait a moment after starting */
#define WBF_DELAY (1<<WBB_DELAY)
#define WBB_CLEANUP 2 /* Cleanup after starting */
#define WBF_CLEANUP (1<<WBB_CLEANUP)
#define WBB_NEWPATH 3 /* Set new Workbench path */
#define WBF_NEWPATH (1<<WBB_NEWPATH)
/*
** Private structures
*/
struct Options
{
LBOOL opt_Debug; /* DEBUG/S */
LBOOL opt_Delay; /* DELAY/S */
LBOOL opt_CleanUp; /* CLEANUP/S */
LBOOL opt_NewPath; /* NEWPATH/S */
LBOOL opt_Hide; /* HIDE/S */
LBOOL opt_RAMIcon; /* RAMICON/S */
}; /* Options */
struct PathEntry
{
BPTR pe_Next; /* Next entry */
BPTR pe_Lock; /* Lock on directory */
}; /* PathEntry */
struct MyDevNode
{
struct MinNode mdn_Node; /* Link */
struct DosList *mdn_Device; /* DOS device pointer */
}; /* MyDevNode */
/*
** Private macros
*/
#define InitList(l) ((l)->lh_Head=(struct Node *)&(l)->lh_Tail,\
(l)->lh_Tail=NULL,\
(l)->lh_TailPred=(struct Node *)&(l)->lh_Head)
/*
** Global data
*/
STATIC CONST TEXT VersionString[]=
VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
/*
** Missing WB prototypes/pragmas
*/
LONG StartWorkbench(LONG flags, BPTR ptr);
#pragma libcall WorkbenchBase UpdateWorkbench 1e 00
#pragma libcall WorkbenchBase QuoteWorkbench 24 00
#pragma libcall WorkbenchBase StartWorkbench 2a 1002
#pragma libcall WorkbenchBase WBConfig 54 00
/*
** Private functions prototypes
*/
/* Not all functions INLINED because of bug in SAS/S 6.50 */
STATIC BPTR GetPathCopy(BPTR path, struct Library *DOSBase);
STATIC VOID FreePathCopy(BPTR path, struct Library *DOSBase);
STATIC INLINE VOID AddDosEntries(struct List *list, struct Library *DOSBase);
STATIC INLINE VOID RemDosEntries(struct List *list, struct Library *DOSBase);
STATIC LBOOL CopyIcon(struct Library *IconBase);
STATIC INLINE LBOOL DeleteIcon(struct Library *IconBase);
/*
** Public functions
*/
/****** C/LoadWB ************************************************************
*
* NAME
* LoadWB -- start Workbench. (V42)
*
* SYNOPSIS
* LoadWB [-DEBUG] [DELAY] [CLEANUP] [NEWPATH] [HIDE] [RAMICON]
*
* TEMPLATE
* LoadWB "DEBUG=-DEBUG/S,DELAY/S,CLEANUP/S,NEWPATH/S,HIDE/S,RAMICON/S"
*
* FUNCTION
* This command will try to load and start Workbench. If RAMICON option
* is used, LoadWB will use 'ENV:Sys/def_ramdisk.info' icon for the
* Ram-Disk icon. If NEWPATH option is used, LoadWB will replace a
* current Workbench search path with a search path of Shell from which
* the LoadWB was issued. If Workbench is already running, the command
* will do nothing (unless NEWPATH or RAMICON option is used).
*
* INPUTS
* -DEBUG - adds 'Debug' menu to the Workbench menus. There are two
* items under this menu:
* 'ROMWack' starts internal ROM debugger, which requires
* a terminal to be connected to the Amiga internal serial
* port.
* 'Flushlibs' removes all libraries, devices and fonts
* currently not in use thus freeing some memory.
* DELAY - forces LoadWB command not to return until Workbench is
* completely initialized (i.e. all disk icons are loaded and
* all WBStartup programs are started). If DELAY option does
* not appear, LoadWB command will return as soon as Workbench
* is started.
* CLEANUP - forces Workbench to execute 'Clean Up' function for main
* Workbench window after starting.
* NEWPATH - lets you change current Workbench path. Normally, Workbench
* remembers path of the Shell that started Workbench. This
* path is inherited by all programs strated from Workbench.
* To change path of already running Workbench, you must use
* NEWPATH option. If Workbench has not been started yet, this
* option is ignored.
* HIDE - Workbench has a habit of putting 'NDOS:???' icons for all
* unrecognized disks. This is very annoying for users of
* CrossDOS and DiskSpare disks. HIDE will force Workbench
* to hide all those 'NDOS:???' icons, including the ones for
* unformatted disks. This option also implies DELAY.
* RAMICON - changes the icon for a Ram-Disk. 'ENV:Sys/def_ramdisk.info'
* is used to represent the new Ram-Disk icon. This option
* can be used to set an icon for newly started Workbench
* or to change the Ram-Disk icon of running Workbench.
* This option also implies DELAY.
*
* RESULT
* RETURN_FAIL - if 'dos.library' or 'workbench.library' couldn't be
* opened or command line arguments couldn't be processed.
* RETURN_ERROR - NEWPATH option was given but copy of current path
* couldn't be made (due to lack of memory).
* RETURN_WARN - Workbench was already running and NEWPATH option was
* not given or RAMICON option was given and there were
* some problems with the Ram-Disk icon.
*
* EXAMPLE
* LoadWB HIDE
* ; Load Workbench, hide all 'NDOS:???' icons. Command will not
* ; return until Workbench is completely initialized.
*
* LoadWB DEBUG CLEANUP
* ; Start Workbench with 'Debug' menu, move all icons after
* ; starting.
*
* LoadWB NEWPATH
* ; Set path of already running Workbench or just start it.
*
* LoadWB RAMICON
* ; Start Workbench and use 'ENV:Sys/def_ramdisk.info' as a
* ; Ram-Disk icon
*
* NOTES
* To hide those 'NDOS:???' icons all DOS devices are removed before
* starting Workbench and restored afterwards. This might affect
* multitasking!
* RAMICON works by copying 'ENV:Sys/def_ramdisk.info' to
* 'RAM:Disk.info' before Workench is started and deleting
* 'RAM:Disk.info' afterwards.
* MakeLink is pure and can be made resident.
*
* BUGS
* LoadWB NEWPATH sometimes hangs for a few seconds. This bug also
* appears in LoadWB 38.9 command.
*
*****************************************************************************
*
*/
LONG LoadWB(VOID)
{
struct ExecBase *SysBase=INITSYSBASE;
struct Library *DOSBase;
struct Library *WorkbenchBase;
struct Library *IconBase=NULL;
struct Options Opts;
struct List DevList;
struct RDArgs *Args;
struct CommandLineInterface *CLI;
APTR ConTask;
BPTR OldLock,PathLock=NULL;
LONG WBFlags=0,RC=RETURN_FAIL;
LBOOL Warn=FALSE;
/* Open DOS */
unless(DOSBase=OpenLibrary(DOS_NAME,DOS_VERN))
throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY), NO_DOS);
/* Open Workbench */
unless(WorkbenchBase=OpenLibrary(WB_NAME,WB_VERN))
throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,PROG_NAME), NO_WB);
/* Read arguments */
clear(&Opts); /* Clear out buffer */
unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
throw2(PrintFault(IoErr(),PROG_NAME), NO_ARGS);
/* Process options */
if(Opts.opt_Debug) fset(WBFlags,WBF_DEBUG);
if(Opts.opt_Delay) fset(WBFlags,WBF_DELAY);
if(Opts.opt_CleanUp) fset(WBFlags,WBF_CLEANUP);
if(Opts.opt_NewPath) fset(WBFlags,WBF_NEWPATH);
if(Opts.opt_Hide) fset(WBFlags,WBF_DELAY);
if(Opts.opt_RAMIcon) fset(WBFlags,WBF_DELAY);
RC=RETURN_OK; /* Working for now... */
/* Get copy of path */
if(CLI=(struct CommandLineInterface *)BADDR(ThisProcessD()->pr_CLI))
if(CLI->cli_CommandDir)
unless(PathLock=GetPathCopy(CLI->cli_CommandDir,DOSBase))
{
PrintFault(IoErr(),PROG_NAME);
RC=RETURN_ERROR;
}
/* Start Workbench */
if(RC<RETURN_ERROR) /* No error copying path */
{
if(Opts.opt_RAMIcon) /* RAMICON option? */
{
IconBase=OpenLibrary(ICON_NAME,ICON_VERN);
unless(CopyIcon(IconBase)) /* Try to copy icon */
Warn=TRUE; /* No success - set warning */
}
InitList(&DevList); /* Set up devices list */
if(Opts.opt_Hide) /* HIDE option? */
RemDosEntries(&DevList,DOSBase); /* Remove all devices */
ConTask=SetConsoleTask(NULL); /* No console task */
OldLock=CurrentDir(NULL); /* Change to root dir */
unless(StartWorkbench(WBFlags,PathLock)) /* StartWorkbench() unsuccessfull*/
{
FreePathCopy(PathLock,DOSBase); /* Free path copy (if any) */
Warn=TRUE; /* Set warning flag */
}
CurrentDir(OldLock); /* Change back to old dir */
SetConsoleTask(ConTask); /* Restore console task */
if(Opts.opt_Hide) /* HIDE option? */
AddDosEntries(&DevList,DOSBase); /* Add back all devices */
if(Opts.opt_RAMIcon) /* RAMICON option? */
{
unless(DeleteIcon(IconBase)) /* Deletion successfull? */
Warn=TRUE; /* No - set warning */
CloseLibrary(IconBase); /* Close icon.library */
}
/* Set result appropriately */
if(Warn) /* Warning condition? */
RC=RETURN_WARN; /* Set result if so */
}
/* Exceptions */
catch(NO_ARGS, FreeArgs(Args));
catch(NO_WB, CloseLibrary(WorkbenchBase));
catch(NO_DOS, CloseLibrary(DOSBase));
return(RC);
} /* LoadWB */
/*
** Private functions
*/
STATIC BPTR GetPathCopy(BPTR path, struct Library *DOSBase)
{
struct ExecBase *SysBase=INITSYSBASE;
struct PathEntry *PE,*NewPE=NULL,*OldPE=NULL;
BPTR Result=NULL;
/* Make a copy of each path entry */
for(PE=BADDR(path); PE; PE=BADDR(PE->pe_Next))
if(new(NewPE,MEMF_PUBCLR))
{
if(OldPE) OldPE->pe_Next=MKBADDR(NewPE);
else Result=MKBADDR(NewPE);
unless(NewPE->pe_Lock=DupLock(PE->pe_Lock))
break;
OldPE=NewPE;
}
/* Check for success */
if(!NewPE || !NewPE->pe_Lock) /* AllocMem() or DupLock() error */
{
FreePathCopy(Result,DOSBase); /* Free alloated memory */
Result=NULL; /* Mark error */
}
/* Return from function */
return(Result);
} /* GetPathCopy */
STATIC VOID FreePathCopy(BPTR path, struct Library *DOSBase)
{
struct ExecBase *SysBase=INITSYSBASE;
struct PathEntry *PE=BADDR(path),*OldPE;
while(PE)
{
OldPE=PE;
PE=BADDR(PE->pe_Next);
UnLock(OldPE->pe_Lock);
delete(OldPE);
}
} /* FreePathCopy */
STATIC INLINE VOID AddDosEntries(struct List *list, struct Library *DOSBase)
{
struct ExecBase *SysBase=INITSYSBASE;
struct DosList *DL;
struct MyDevNode *MDN;
if(DL=LockDosList(LDF_DEVICES | LDF_WRITE)) /* Lock list of DOS devices */
{
while(MDN=(struct MyDevNode *)RemHead(list))/* For each node on list */
{
if(MDN->mdn_Device) /* Device pointer valid */
AddDosEntry(MDN->mdn_Device); /* Add to DOS list */
delete(MDN); /* Free memory */
}
UnLockDosList(LDF_DEVICES | LDF_WRITE); /* Unlock list of DOS devices */
}
} /* AddDosEntries */
STATIC INLINE VOID RemDosEntries(struct List *list, struct Library *DOSBase)
{
struct ExecBase *SysBase=INITSYSBASE;
struct DosList *DL;
struct MyDevNode *MDN;
if(DL=LockDosList(LDF_DEVICES | LDF_WRITE)) /* Lock list of DOS devices */
{ /* Locking successfull */
while(DL=NextDosEntry(DL,LDF_DEVICES)) /* For each device on list */
if(new(MDN,MEMF_PUBCLR)) /* Try to allocate memory for it */
{ /* Allocation successfull */
if(RemDosEntry(DL)) /* Try to remove entry */
MDN->mdn_Device=DL; /* Remember device pointer */
AddHead(list,(struct Node *)MDN); /* Add to list */
}
UnLockDosList(LDF_DEVICES | LDF_WRITE); /* Unlock list of DOS devices */
}
} /* RemDosEntries */
STATIC LBOOL CopyIcon(struct Library *IconBase)
{
struct DiskObject *Icon;
LBOOL RC=FALSE;
if(IconBase)
if(Icon=GetDiskObject(SRC_ICON))
RC=PutDiskObject(DST_ICON,Icon);
return(RC);
} /* CopyIcon */
STATIC INLINE LBOOL DeleteIcon(struct Library *IconBase)
{
LBOOL RC=FALSE;
if(IconBase)
RC=DeleteDiskObject(DST_ICON);
return(RC);
} /* DeleteIcon */